android 配置虚拟机内存 安卓虚拟机运行机制

您所在的位置:网站首页 安卓11 虚拟内存 android 配置虚拟机内存 安卓虚拟机运行机制

android 配置虚拟机内存 安卓虚拟机运行机制

2023-07-07 15:29| 来源: 网络整理| 查看: 265

定义:

在模拟真实机器执行程序之前,将程序的指令和数据装载进入虚拟机内部的运行时环境,使虚拟机中的执行模块可以根据程序执行的需要随时取得目标指令和相关数据,以完成程序的执行任务。

作用:

将应用程序中Dalvik操作码以及程序数据提取并加载到虚拟机内部,以保证程序的正常运行。

首先来一个图,看看类加载机制位于Dalvik虚拟机的什么位置

                                                       

android 配置虚拟机内存 安卓虚拟机运行机制_类加载机制

从这里可以看到,类加载机制位于虚拟机初始化进程之前,结束于字节码流执行。

我们可以从上图看到,类加载机制的整体工作流程分三步:

1.验证优化,验证主要验证dex文件的合法性、安全性,优化则输出oDex文件

2.解析Odex文件,在内存中创建专用的数据结构描述该文件

3.加载Odex文件解析后的类数据,到运行时的数据结构中,以供解释器执行。

不太明白的可以看图

                                         

android 配置虚拟机内存 安卓虚拟机运行机制_类加载机制_02

看到这里,大概知道类加载机制做了哪些事情了,现在我们来分解步骤进行解读。

首先讲解Dex文件验证优化的原理

还是首先看看优化工作流程

                                                  

android 配置虚拟机内存 安卓虚拟机运行机制_android 配置虚拟机内存_03

优化机制的优点在于:

1.Dalvik的优化验证独立于程序执行

2.优化验证机制模块化,降低了Android系统的冗余

3.让应用程序第二次启动速度变快,android应用程序第一次启动的时候,生成了Odex文件,第二次的时候,不需要对原Dex进行解析,直接引用执行已经生成的ODex文件,大大缩短了应用的执行时间。

接下来看一下Odex文件结构与Dex文件结构的区别,首先还是看一张图

android 配置虚拟机内存 安卓虚拟机运行机制_类加载机制_04

从图中可以看出,Odex文件是在Dex文件基础上的优化,加上了自己特有的文件头部,依赖库信息,以及辅助信息。

Odex文件(DexOptHeader)头部:包括了版本号、偏移量、总长度等信息

依赖库信息数据结构:包括了时间、校验信息、版本号等信息

类索引辅助信息,主要用于定位类资源地址并加载类;

其中DexClassLookUp:包括了表大小、表项入口数量、类描述符的哈希值等

最后我们得通过源码来看函数具体执行的流程

1.Dex文件优化始于PackageManagerService,源码位置位于/install/remove/dexopt/

2.在dexOpt方法中创建Odex文件,源码位置位于dalvik/dexOpt

3.dexOpt的主程序代码位于dalvik/dexopt/OptMain.cpp文件中,其中extractAndProcessZip()方法用于处理并优化apk/jar/zip文件中的classes.dex文件,

接下来我们来看extractAndProcessZip()的代码

static int extractAndProcessZip (int zipFd,int cacheFd,const char* debugFileName, bool isBootstrap,const char* bootClassPath,const char* dexoptFlagStr) { /*函数在执行初期声明相关的中间变量*/ ZipArchive zippy; //用于描述ZIP压缩文件的数据结构 ZipEntry zipEntry; //用于表示一个ZIP入口 ... off_t dexOffset; //用于表示在Odex文件中,原Dex文件的起始地址 int err; //标示符 int result=-1; //函数返回值 int dexoptFlags=0; //优化标示符 /*设置默认的优化模式*/ DexClassVerifyMode verifyMode=VERIFY_MODE_ALL; DexOptimizerMode dexOptMode=OPTIMIZE_MODE_VERIFIED; memset(&zippy,0,sizeof(zippy)); //对zippy对象进行置0操作 /*对入口参数cacheFd文件描述符所代表的输入文件进行为空判断,该文件必须保证为空,因 为在后期要将优化后的数据写入该文件中*/ if (lseek(cacheFd,0,SEEK_END) !=0) { LOGE("DexOptZ:new cache file '%s' is not empty",debugFileName); goto bail; } /*当cacheFd所指文件为空,那么为其创建一个Odex文件的头部*/ err=dexOptCreateEmptyHeader(cacheFd); if (err !=0) //对函数执行结果进行判断,如果失败则将返回 goto bail; /*取得Odex文件中原Dex文件的起始位置,实际就是一个Odex文件头部的长度,并将结果赋值 给变量dexOffset*/ dexOffset=lseek(cacheFd,0,SEEK_CUR); if (dexOffset


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3